package com.salt.modules.sys.service;

import com.salt.common.config.properties.SaltProperites;
import com.salt.common.config.web.Servlets;
import com.salt.common.json.AjaxJson;
import com.salt.core.log.utils.LoginRecordUtils;
import com.salt.core.redis.cache.SaltRedis;
import com.salt.core.sms.SmsTemplate;
import com.salt.core.sms.model.SmsCode;
import com.salt.modules.log.enums.BusinessStatus;
import com.salt.modules.log.enums.LoginRegisterType;
import com.salt.modules.sys.entity.User;
import com.salt.modules.sys.entity.UserLoginParam;
import com.salt.modules.sys.security.util.JWTUtil;
import com.salt.modules.sys.utils.UserUtils;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Duration;
import java.util.Objects;

import static com.salt.core.redis.constant.CacheName.SALT_SYSTEM_LOGIN_TYPE;

/**
 * @Description
 * @Author salt
 * @Date 2022/9/8
 * @Version 1.0.1
 */
@Service
@AllArgsConstructor
@Transactional(readOnly = true)
public class LoginService {

    private final SmsTemplate smsTemplate;
    private final SaltRedis saltRedis;

    private static final long SALT_SYSTEM_LOGIN_TYPE_DDL = 12;

    public AjaxJson login(String userName, String password) {
        User user = UserUtils.getByLoginName(userName);
        /*if (!user.isAdmin())
            return AjaxJson.error("您没有权限登录该平台!");*/

        AjaxJson j = new AjaxJson();
        if (user != null && UserService.validatePassword(password, user.getPassword())) {
            if (SaltProperites.NO.equals(user.getLoginFlag())){
                j.setSuccess(false);
                j.setMsg("该用户已经被禁止登陆!");

                LoginRecordUtils.senderLog(Servlets.getRequest(), user.getId(), user.getName(), userName, BusinessStatus.FAIL.name(), LoginRegisterType.LONGIN.name(), "该用户已经被禁止登陆");
            } else {
                j.setSuccess(true);
                j.put(JWTUtil.TOKEN, JWTUtil.createAccessToken(userName, user.getPassword(), user.getName(), user.getId()));
                j.put(JWTUtil.REFRESH_TOKEN, JWTUtil.createRefreshToken(userName, user.getPassword(), user.getName(), user.getId()));
                cachLoginSystemType(user.getId(), "3");

                // 记录登录日志
                LoginRecordUtils.senderLog(Servlets.getRequest(), user.getId(), user.getName(), userName, BusinessStatus.SUCCESS.name(), LoginRegisterType.LONGIN.name(), "PC端登陆成功");
            }
        } else {
            j.setSuccess(false);
            j.setMsg("用户名或者密码错误!");

            //LoginRecordUtils.senderLog(Servlets.getRequest(), userName, BusinessStatus.FAIL.name(), LoginRegisterType.LONGIN.name(),"用户名或者密码错误");
        }
        return j;
    }

    public AjaxJson login(UserLoginParam userLoginParam) {
        User user = null;
        boolean loginFlag = false;
        String type = userLoginParam.getType();
        String username = null;
        if (Objects.equals(type, "1")) { //
            if (StringUtils.isBlank(userLoginParam.getLoginName())) {
                //LoginRecordUtils.senderLog(Servlets.getRequest(), userLoginParam.getLoginName(), BusinessStatus.FAIL.name(), LoginRegisterType.LONGIN.name(), "账号为空");
                return AjaxJson.error("账号不能为空!");
            }

            user = UserUtils.getByLoginName(userLoginParam.getLoginName());
            if (user == null) {
                //LoginRecordUtils.senderLog(Servlets.getRequest(), userLoginParam.getLoginName(), BusinessStatus.FAIL.name(), LoginRegisterType.LONGIN.name(), "尚未注册");
                return AjaxJson.error("该用户尚未注册,请先注册!");
            }

            if (UserService.validatePassword(userLoginParam.getPassword(), user.getPassword())){
                loginFlag = true;
                username = userLoginParam.getLoginName();
            }
        } else if (Objects.equals(type, "2") || Objects.equals(type, "3")) {
            if (StringUtils.isBlank(userLoginParam.getMobile())) {
                //LoginRecordUtils.senderLog(Servlets.getRequest(), userLoginParam.getLoginName(), BusinessStatus.FAIL.name(), LoginRegisterType.LONGIN.name(), "手机号为空");
                return AjaxJson.error("手机号不能为空!");
            }


            String mobile = userLoginParam.getMobile().replaceAll("\\s*", "");
            user = UserUtils.getByMobile(mobile);
            if (user == null) {
                //LoginRecordUtils.senderLog(Servlets.getRequest(), userLoginParam.getLoginName(), BusinessStatus.FAIL.name(), LoginRegisterType.LONGIN.name(), "尚未注册");
                return AjaxJson.error("该用户尚未注册,请先注册!");
            }

            if (Objects.equals(type, "2")) {
                SmsCode smsCode = new SmsCode()
                        .setId(userLoginParam.getValidate() + mobile)
                        .setValue(userLoginParam.getSmsCode());
                if (!smsTemplate.validateMessage(smsCode)) {
                    //LoginRecordUtils.senderLog(Servlets.getRequest(), userLoginParam.getLoginName(), BusinessStatus.FAIL.name(), LoginRegisterType.LONGIN.name(), "手机验证码有误");
                    return AjaxJson.error("手机验证码有误!");
                }

            }
            loginFlag = true;
            username = user.getLoginName();
        }

        AjaxJson j = new AjaxJson();
        if (loginFlag) {
            if (SaltProperites.NO.equals(user.getLoginFlag())){
                j.setSuccess(false);
                j.setMsg("该用户已经被禁止登陆!");
                //LoginRecordUtils.senderLog(Servlets.getRequest(), username, BusinessStatus.FAIL.name(), LoginRegisterType.LONGIN.name(), "该用户已经被禁止登陆");
            } else {
                j.setSuccess(true);
                j.put(JWTUtil.TOKEN, JWTUtil.createAccessToken(username, user.getPassword(), user.getName(), user.getId()));
                j.put(JWTUtil.REFRESH_TOKEN, JWTUtil.createRefreshToken(username, user.getPassword(), user.getName(), user.getId()));
                cachLoginSystemType(user.getId(), userLoginParam.getSystemType());

                // 记录登录日志
                //LogUtils.saveLog(Servlets.getRequest(), "系统登录", LogType.LOGIN.getType());
                LoginRecordUtils.senderLog(Servlets.getRequest(), user.getId(), user.getName(), username, BusinessStatus.SUCCESS.name(), LoginRegisterType.LONGIN.name(), "PC端登陆成功");
            }
        } else {
            j.setSuccess(false);
            j.setMsg("手机号或者密码错误!");
            //LoginRecordUtils.senderLog(Servlets.getRequest(), username, BusinessStatus.FAIL.name(), LoginRegisterType.LONGIN.name(),"用户名或者密码错误");

        }

        return j;
    }

    private void cachLoginSystemType(String userId, String systemType) {
        String key = getCachLoginSystemTypeKey(userId);
        if (saltRedis.exists(key))
            saltRedis.del(key);
        saltRedis.set(key, systemType, Duration.ofHours(SALT_SYSTEM_LOGIN_TYPE_DDL));

    }

    public void refreshLoginSystemType(String userId) {
        String systemType = getCachLoginSystemType(userId);
        this.cachLoginSystemType(userId, systemType);
    }

    public String getCachLoginSystemType(String userId) {
        return saltRedis.get(getCachLoginSystemTypeKey(userId));
    }

    public void removeLoginSystemType(String userId) {
        String key = getCachLoginSystemTypeKey(userId);
        if (saltRedis.exists(key))
            saltRedis.del(key);
    }

    private String getCachLoginSystemTypeKey(String userId) {
        return SALT_SYSTEM_LOGIN_TYPE + userId;
    }
}
